package com.example.net.http

import android.util.Log
import com.example.baseutils.*
import com.example.baseutils.Constance.CHAT_BASE_URL
import com.example.baseutils.application.BaseApplication
import com.example.net.http.request.*
import com.example.net.http.response.*
import com.example.net.utils.HttpUtils
import com.example.net.utils.SecurityUtils
import com.google.gson.Gson
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import okio.Buffer
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import java.io.File
import java.nio.charset.Charset
import java.util.concurrent.TimeUnit


/**
 * Author by lp,on 2020/8/27/027,11:19.
 * 请求信息
 */
object ChatRetrofitCreator {
    private val TAG = "ChatRetrofitCreator"


    var accessToken = MySharedPreferences.read(Constance.Authorization, "") ?: ""
    var expireTime = MySharedPreferences.read(Constance.EXPIRESTIME, -1L) ?: -1L

    //拦截者
    private val headerInterceptor = Interceptor { chain ->
        val deviceNo =
            AppUtils.getLocalMacAddressFromWifiInfo()
        val request = chain.request().newBuilder().addHeader("deviceNo", deviceNo)
            .addHeader("device_no", deviceNo).build()
        Log.i("RetrofitCreator", "request body $deviceNo: $request")
        val response = chain.proceed(request)
        response
    }


    val httpLoggingInterceptor = HttpLoggingInterceptor().apply {

        level = HttpLoggingInterceptor.Level.BODY
    }

    private val chatClient = OkHttpClient.Builder().addInterceptor(cacheInterceptor())
        .addInterceptor(httpLoggingInterceptor)
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(10, TimeUnit.SECONDS)
//        .retryOnConnectionFailure(true)
        .writeTimeout(10, TimeUnit.SECONDS)
        .build()

    private val chatRetrofit = Retrofit.Builder()
        .baseUrl(CHAT_BASE_URL)
        .client(chatClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build()




    val chatService: ChatService = chatRetrofit.create(ChatService::class.java)
    /**
     * 缓存数据拦截器
     *
     * @param mContext Context
     * @param key      秘钥
     */
    private class cacheInterceptor() : Interceptor {
        override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
            val request = chain.request().newBuilder()
                .addHeader("Authorization", "$accessToken")
                .addHeader("api-version", "v2")
                .addHeader("content-type", "application/json")
                .build()


            val requestBody = request.body
            var body = "null"
            if (requestBody != null) {
                val buffer = Buffer()
                requestBody.writeTo(buffer)
                var charset: Charset = java.nio.charset.StandardCharsets.UTF_8
                body = buffer.readString(charset)
            }
            val requestJson = body
            Log.i(TAG, "cacheInterceptor: requestJson $requestJson")
            if (!requestJson.contains("appKey")) {
                val response = chain.proceed(request)
                Log.i(TAG, "非cacheTime: ")
                return response
            }
            Log.e(TAG, "缓存的接口" )
            Log.i(TAG, "expiresTime:$expireTime ")
            // 缓存时间
            val cacheKey = HttpUtils.getCacheKey(request)
            var key = cacheKey
            val cacheFile = File(HttpUtils.getCacheFile(BaseApplication.instance), cacheKey)
            val cacheEnable = (System.currentTimeMillis()/1000L - expireTime) <0
            Log.i(TAG, "cacheEnable: $cacheEnable")
            if (cacheEnable && cacheFile.exists() && cacheFile.length() > 0) {
                Log.e(
                    TAG,
                    "[intercept] 缓存模式 url:${HttpUtils.getRequestUrl(request)} " + "过期时间:${
                        HttpUtils.dateTimeToString(expireTime)
                    }"
                )
                val cache = SecurityUtils.decryptContent(cacheFile.readText(), key)
                if (cache.isNotEmpty() && cache.startsWith("{") && cache.endsWith("}")) {
                    Log.i(TAG, "from disk cache: $cache")
                    return okhttp3.Response.Builder()
                        .code(200)
                        .body(cache.toResponseBody())
                        .request(request)
                        .message("from disk cache")
                        .protocol(Protocol.HTTP_2)
                        .build()
                }
            }
            val response = chain.proceed(request)
            //response.body?.string()只能读取一次 就流会被close
            val dataString = response.body?.string() ?: return response
            // 写入缓存
            if (response.code == 200) {
                Log.i(TAG, "-------save cache--------")
                // Json数据写入缓存
                cacheFile.writeText(SecurityUtils.encryptContent(dataString, key))
            } else {
                Log.i(TAG, "-------response error--------" + response.message)
                cacheFile.writeText("")
            }
            return response.newBuilder()
                .message(response.message)
                .body(dataString.toResponseBody(response.body?.contentType()))
                .build()
        }
    }




    private fun saveToken(token: String,expire:Long) {
        if (accessToken == token||token.isNullOrEmpty()) {
            Log.e(TAG, "saveToken: 无需更新")
            return
        }
        accessToken = token
        expireTime=expire
        Log.e(TAG, "saveToken 更新accessToken $accessToken")
        MySharedPreferences.save {
            putString(Constance.Authorization, accessToken)
            putLong(Constance.EXPIRESTIME, expireTime)
        }
    }

    /**
     *
     * 登录
     * */
    suspend fun login(appKey: String, secret: String): Boolean {
        Log.i(TAG, "login before ")
        val request = ChatLoginRequest(appKey,secret)
        try {
            val requestJson = Gson().toJson(request)
            Log.i(TAG, "login  requestJson $requestJson")
            val requestBody =
                RequestBody.create(
                    "application/json;charset=utf-8".toMediaTypeOrNull(),
                    requestJson
                )
            val result = chatService.loginChat(requestBody)
            saveToken(result.accessToken,result.expires)
            "login result $result".log(TAG)
            return true
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e(TAG, "${e.message}")
        }
        return false
    }
    /**
     *
     * 注册
     * */
    suspend fun register(): ChatRegistResponse? {
        Log.i(TAG, "register before ")
        val request = ChatRegisterRequest()
        try {
            val requestJson = Gson().toJson(request)
            Log.i(TAG, "register  requestJson $requestJson")
            val requestBody =
                RequestBody.create(
                    "application/json;charset=utf-8".toMediaTypeOrNull(),
                    requestJson
                )
            val result = chatService.registerUser(requestBody)
            "register result $result".log(TAG)
            return result
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e(TAG, "${e.message}")
        }
        return null
    }
    /**
     *
     * 获取机器人列表
     * */
    suspend fun getRobots(): ArrayList<ChatRobotItemResponse>? {
        Log.i(TAG, "getRobots before ")
        try {
            val result = chatService.getRobotList()
            "getRobots result $result".log(TAG)
            return result
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e(TAG, "${e.message}")
        }
        return null
    }

    /**
     *
     * 唤醒机器人
     * */
    suspend fun wakeUpRobot(uid:String,robotId:String,sessionId:String): Boolean {
        Log.i(TAG, "wakeUpRobot before ")
        try {
            val request=ChatWakeRequest(uid,robotId,sessionId,10)
            val requestJson=Gson().toJson(request)
            val requestBody =
                RequestBody.create(
                    "application/json;charset=utf-8".toMediaTypeOrNull(),
                    requestJson
                )
            val result = chatService.wakeUpChat(requestBody)
            "wakeUpRobot result $result".log(TAG)
            return true
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e(TAG, "${e.message}")
        }
        return false
    }



}

